import pygame
import sys
import random
from .utils import load_achievements, save_achievements  # 确保导入这些函数

'''用户界面元素'''

def draw_button(screen, text, position, size, color, hover_color, cfg, font, text_color=None, is_selected=False, border_width=3):
    """绘制按钮并返回按钮矩形"""
    if text_color is None:
        text_color = cfg.WHITE # Default text color

    # Adjust text color for selected state for better contrast on light backgrounds
    if is_selected:
        # If button color is light (like Yellow), use black text when selected.
        # Simple check: if sum of RGB > 384 (midpoint), consider it light.
        if sum(color) > 384:
             text_color = cfg.BLACK
        else:
             text_color = cfg.WHITE # Keep white text on dark selected buttons

    text_surface = font.render(text, True, text_color)
    text_rect = text_surface.get_rect(center=position)
    button_rect = pygame.Rect(0, 0, size[0], size[1])
    button_rect.center = position

    mouse_pos = pygame.mouse.get_pos()
    is_hovered = button_rect.collidepoint(mouse_pos)

    # Determine button background color
    current_color = color
    if is_selected:
        # Make selected button slightly lighter/brighter than base color, or use hover color
        # Example: brighten the base color slightly
        current_color = tuple(min(c + 30, 255) for c in color)
    if is_hovered:
        current_color = hover_color # Hover overrides selection brightening

    pygame.draw.rect(screen, current_color, button_rect, border_radius=10)

    # Draw border if selected OR hovered
    if is_selected or is_hovered:
        pygame.draw.rect(screen, cfg.WHITE, button_rect, width=border_width, border_radius=10)

    screen.blit(text_surface, text_rect)
    return button_rect

def start_menu(screen, cfg, current_color_value, current_difficulty):
    """显示开始菜单 (Wider layout)"""
    # Find the name corresponding to the current color value for default selection
    current_color_name = next((name for name, value in cfg.SNAKE_COLOR_OPTIONS.items() if value == current_color_value), list(cfg.SNAKE_COLOR_OPTIONS.keys())[0])
    selected_color_name = current_color_name
    selected_difficulty = current_difficulty
    selected_mode = None # Mode is selected by clicking its button
    menu_active = True

    # Background effect (random squares)
    background_rects = []
    for _ in range(100): # More squares for wider screen
        x = random.randint(0, cfg.WIDTH)
        y = random.randint(0, cfg.HEIGHT)
        size = random.randint(cfg.GRID_SIZE // 2, cfg.GRID_SIZE)
        color_tuple = random.choice(list(cfg.SNAKE_COLOR_OPTIONS.values()))
        alpha = random.randint(30, 100)
        background_rects.append((x, y, size, color_tuple, alpha))

    while menu_active:
        screen.fill(cfg.BLACK)
        # Draw background effect
        for x, y, size, color, alpha in background_rects:
             s = pygame.Surface((size, size), pygame.SRCALPHA)
             color_with_alpha = color + (alpha,)
             s.fill(color_with_alpha)
             screen.blit(s, (x, y))

        # Title
        title = cfg.FONT_MAIN_LARGE.render("贪吃蛇 大作战", True, cfg.WHITE)
        title_rect = title.get_rect(center=(cfg.WIDTH // 2, 80))
        title_bg = title_rect.inflate(160, 60)
        pygame.draw.rect(screen, cfg.DARK_GRAY, title_bg, border_radius=20)
        pygame.draw.rect(screen, cfg.WHITE, title_bg, width=3, border_radius=20)
        screen.blit(title, title_rect)

        # --- Layout Calculations (for WIDTH=1200) ---
        col_width = cfg.WIDTH // 3 # 1200 / 3 = 400
        col_center_left = col_width // 2 # 200
        col_center_mid = col_width + col_width // 2 # 600
        col_center_right = 2 * col_width + col_width // 2 # 1000
        panel_margin = 40 # Increased margin
        panel_width = col_width - 2 * panel_margin # 400 - 80 = 320
        panel_height = 580 # Increased height to fit color buttons
        panel_y = 140 # Slightly lower start Y

        # Panel drawing helper
        def draw_panel(center_x):
            panel_rect = pygame.Rect(0, 0, panel_width, panel_height)
            panel_rect.center = (center_x, panel_y + panel_height // 2)
            panel_surface = pygame.Surface(panel_rect.size, pygame.SRCALPHA)
            panel_surface.fill((30, 30, 30, 210)) # Slightly more opaque
            screen.blit(panel_surface, panel_rect.topleft)
            pygame.draw.rect(screen, cfg.LIGHT_GRAY, panel_rect, width=2, border_radius=15)
            return panel_rect

        # --- Left Column: Instructions ---
        instr_panel_rect = draw_panel(col_center_left)
        instr_title = cfg.FONT_MAIN_MEDIUM.render("游戏说明", True, cfg.WHITE)
        instr_title_rect = instr_title.get_rect(center=(col_center_left, panel_y + 40))
        screen.blit(instr_title, instr_title_rect)

        instructions = [
            "方向键移动", "吃红(+)得分", "吃蓝(-)缩短",
            "白色方块是陷阱", "空格暂停", "ESC返回菜单",
            "完成目标分数进阶"
        ]
        instr_start_y = panel_y + 90
        instr_y_gap = 45
        for i, instruction in enumerate(instructions):
            instr_text = cfg.FONT_MAIN_SMALL.render(instruction, True, cfg.WHITE)
            # Center instructions text within the panel
            instr_text_rect = instr_text.get_rect(center=(col_center_left, instr_start_y + i * instr_y_gap))
            # instr_text_rect = instr_text.get_rect(midleft=(instr_panel_rect.left + 30, instr_start_y + i * instr_y_gap)) # Align left
            screen.blit(instr_text, instr_text_rect)

        # --- Middle Column: Settings ---
        settings_panel_rect = draw_panel(col_center_mid)

        # Difficulty Selection
        diff_title = cfg.FONT_MAIN_MEDIUM.render("选择难度", True, cfg.WHITE)
        diff_title_rect = diff_title.get_rect(center=(col_center_mid, panel_y + 40))
        screen.blit(diff_title, diff_title_rect)

        difficulty_buttons = []
        diff_button_width = panel_width * 0.75 # Relative width
        diff_button_size = (diff_button_width, 50)
        diff_start_y = panel_y + 90
        diff_y_gap = 65
        diff_colors = {"简单": cfg.GREEN, "普通": cfg.YELLOW, "困难": cfg.RED}
        for i, diff_name in enumerate(cfg.DIFFICULTY_SETTINGS.keys()):
            is_selected = (diff_name == selected_difficulty)
            button_pos = (col_center_mid, diff_start_y + i * diff_y_gap)
            btn_color = diff_colors.get(diff_name, cfg.GRAY)
            # Text color logic moved inside draw_button for consistency
            button_rect = draw_button(screen, diff_name, button_pos, diff_button_size,
                                      btn_color, cfg.LIGHT_GRAY, cfg, cfg.FONT_MAIN_MEDIUM,
                                      is_selected=is_selected)
            difficulty_buttons.append((button_rect, diff_name))

        # Color Selection
        color_title_y = diff_start_y + len(cfg.DIFFICULTY_SETTINGS) * diff_y_gap + 30 # Adjusted position
        color_title = cfg.FONT_MAIN_MEDIUM.render("选择颜色", True, cfg.WHITE)
        color_title_rect = color_title.get_rect(center=(col_center_mid, color_title_y ))
        screen.blit(color_title, color_title_rect)

        color_buttons = []
        color_button_width = panel_width * 0.75 # Relative width
        color_button_size = (color_button_width, 50)
        color_start_y = color_title_y + 55 # Start below title
        color_y_gap = 55
        display_colors = list(cfg.SNAKE_COLOR_OPTIONS.items())

        for i, (color_name, color_value) in enumerate(display_colors):
             is_selected = (color_name == selected_color_name)
             button_pos = (col_center_mid, color_start_y + i * color_y_gap)
             # Check if button fits within the increased panel height
             if button_pos[1] + color_button_size[1]/2 > panel_y + panel_height - 20:

                  print(f"警告: 颜色按钮 '{color_name}' 可能超出面板边界。")
                  # Consider breaking if too many colors for the panel height
                  # break

             # Use black text for all color buttons for readability on colored background
             button_rect = draw_button(screen, color_name, button_pos, color_button_size,
                                     color_value, cfg.WHITE, cfg, cfg.FONT_MAIN_MEDIUM,
                                     text_color=cfg.BLACK, # Explicitly black text
                                     is_selected=is_selected)
             color_buttons.append((button_rect, color_name))

        # --- Right Column: Mode ---
        mode_panel_rect = draw_panel(col_center_right)
        mode_title = cfg.FONT_MAIN_MEDIUM.render("选择模式", True, cfg.WHITE)
        mode_title_rect = mode_title.get_rect(center=(col_center_right, panel_y + 40))
        screen.blit(mode_title, mode_title_rect)

        mode_buttons = []
        mode_button_width = panel_width * 0.85 # Relative width
        mode_button_size = (mode_button_width, 70)
        mode_start_y = panel_y + 180 # Position lower
        mode_y_gap = 100
        modes = ["关卡模式", "传统模式"]
        for i, mode in enumerate(modes):
            button_pos = (col_center_right, mode_start_y + i * mode_y_gap)
            button_rect = draw_button(screen, mode, button_pos, mode_button_size,
                                    cfg.DARK_GRAY, cfg.GRAY, cfg, cfg.FONT_MAIN_LARGE,
                                    text_color=cfg.WHITE,
                                    is_selected=False) # Mode buttons are actions, not selections
            mode_buttons.append((button_rect, mode))

        # Achievements Button
        achievements_button_width = panel_width * 0.75 # Relative width
        achievements_button_size = (achievements_button_width, 55)
        achievements_button_pos = (col_center_right, mode_start_y + len(modes) * mode_y_gap + 30)
        achievements_button_rect = draw_button(screen, "成就排行榜", achievements_button_pos, achievements_button_size,
                                               cfg.GOLD, cfg.LIGHT_GRAY, cfg, cfg.FONT_MAIN_MEDIUM,
                                               text_color=cfg.BLACK, is_selected=False)

        # Quit Button (Bottom of right panel)
        quit_button_width = panel_width * 0.75 # Relative width
        quit_button_size = (quit_button_width, 55)
        # Position relative to panel bottom
        quit_button_pos = (col_center_right, panel_y + panel_height - 60)
        quit_button_rect = draw_button(screen, "退出游戏", quit_button_pos, quit_button_size,
                                       (150, 0, 0), (200, 50, 50), cfg, cfg.FONT_MAIN_MEDIUM,
                                       text_color=cfg.WHITE, is_selected=False)

        pygame.display.update()

        # --- Event Handling ---
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return None # Indicate quit
            if event.type == pygame.KEYDOWN:
                 if event.key == pygame.K_ESCAPE: # Allow Esc to quit
                      return None # Indicate quit
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1: # Left mouse button
                    mouse_pos = event.pos

                    # Check Difficulty Buttons
                    clicked_difficulty = False
                    for button_rect, diff_name in difficulty_buttons:
                        if button_rect.collidepoint(mouse_pos):
                            selected_difficulty = diff_name
                            clicked_difficulty = True
                            # Don't break, allow changing color too

                    # Check Color Buttons
                    clicked_color = False
                    for button_rect, color_name in color_buttons:
                        if button_rect.collidepoint(mouse_pos):
                            selected_color_name = color_name
                            clicked_color = True
                            # Don't break

                    # Check Mode Buttons (Clicking these ends the menu)
                    clicked_mode = False
                    for button_rect, mode in mode_buttons:
                        if button_rect.collidepoint(mouse_pos):
                            selected_mode = mode
                            menu_active = False # Exit menu loop
                            clicked_mode = True
                            break # Mode selected, stop checking buttons

                    # Check Achievements Button
                    if achievements_button_rect.collidepoint(mouse_pos):
                        show_achievements(screen, cfg)

                    # Check Quit Button
                    if quit_button_rect.collidepoint(mouse_pos):
                        return None # Indicate quit

                # If a mode was selected, break from event loop
                if not menu_active:
                    break

    # If menu loop finished (mode selected), return choices
    if selected_mode:
         return cfg.SNAKE_COLOR_OPTIONS[selected_color_name], selected_mode, selected_difficulty
    else: # If loop exited some other way (shouldn't happen with current logic)
         return None # Indicate failure or quit

def display_pause_message(screen, cfg):
    """显示暂停信息"""
    # Create semi-transparent overlay for the whole screen during pause? Or just the message box.
    # Just the message box is usually less intrusive.
    pause_text = cfg.FONT_MAIN_MEDIUM.render("游戏暂停 (按空格继续)", True, cfg.WHITE)
    pause_rect = pause_text.get_rect(center=(cfg.WIDTH // 2, cfg.HEIGHT // 2))
    # Semi-transparent background for the text
    bg_rect = pause_rect.inflate(40, 20)
    bg_surface = pygame.Surface(bg_rect.size, pygame.SRCALPHA)
    bg_surface.fill((0, 0, 0, 190)) # Darker background
    screen.blit(bg_surface, bg_rect.topleft)
    screen.blit(pause_text, pause_rect)
    # No display.update here, it happens in the main loop's pause section

def display_level_transition(screen, cfg, level_num):
     """显示关卡过渡信息"""
     screen.fill(cfg.BLACK) # Clear screen fully
     message1 = f"关卡 {level_num -1} 完成!"
     message2 = f"准备进入 关卡 {level_num}"
     font_big = cfg.FONT_MAIN_LARGE
     font_small = cfg.FONT_MAIN_MEDIUM
     color = cfg.GREEN

     text1_surf = font_big.render(message1, True, color)
     text1_rect = text1_surf.get_rect(center=(cfg.WIDTH // 2, cfg.HEIGHT // 2 - 50)) # Adjust vertical spacing

     text2_surf = font_small.render(message2, True, cfg.WHITE)
     text2_rect = text2_surf.get_rect(center=(cfg.WIDTH // 2, cfg.HEIGHT // 2 + 40)) # Adjust vertical spacing

     screen.blit(text1_surf, text1_rect)
     screen.blit(text2_surf, text2_rect)
     pygame.display.flip() # Update the display to show the message
     pygame.time.wait(2000) # Pause for 2 seconds

def end_interface(screen, cfg, score, high_score, mode_played, level_played=None):
    """游戏结束界面 (Using specified fonts and layout)"""
    interface_active = True

    # Semi-transparent overlay
    overlay = pygame.Surface(cfg.SCREENSIZE, pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 210)) # Darker overlay

    # Button settings
    button_width, button_height = 200, 60 # Slightly larger buttons
    button_y = cfg.HEIGHT * 0.78 # Position buttons lower
    button_gap = 50 # Wider gap
    # Center buttons horizontally
    total_button_width = 3 * button_width + 2 * button_gap
    start_x = (cfg.WIDTH - total_button_width) / 2
    restart_x = start_x + button_width / 2
    menu_x = restart_x + button_width + button_gap # Corrected calculation
    quit_x = menu_x + button_width + button_gap # Corrected calculation

    while interface_active:
        screen.blit(overlay, (0, 0)) # Draw overlay first

        # --- Display Information ---
        y_pos = cfg.HEIGHT * 0.2 # Start position for text

        # Game Over Title
        title_surf = cfg.FONT_MAIN_XLARGE.render("游戏结束", True, cfg.RED)
        title_rect = title_surf.get_rect(center=(cfg.WIDTH // 2, y_pos))
        screen.blit(title_surf, title_rect)
        y_pos += title_rect.height + 50 # Increased gap

        # Mode Info
        mode_str = f"模式: {mode_played}"
        if mode_played == "关卡模式":
             all_levels_cleared = level_played is not None and level_played > cfg.MAX_LEVEL
             if all_levels_cleared:
                 status = " (已通关!)"
             elif level_played is not None:
                  status = f" (止步 关卡 {level_played})"
             else: # Should not happen if mode is level mode, but safeguard
                  status = ""
             mode_str += status
        mode_surf = cfg.FONT_MAIN_MEDIUM.render(mode_str, True, cfg.WHITE)
        mode_rect = mode_surf.get_rect(center=(cfg.WIDTH // 2, y_pos))
        screen.blit(mode_surf, mode_rect)
        y_pos += mode_rect.height + 40 # Increased gap

        # Score Info (Label + Number)
        score_label_surf = cfg.FONT_MAIN_MEDIUM.render("最终得分: ", True, cfg.WHITE)
        score_num_surf = cfg.FONT_SCORE.render(str(score), True, cfg.WHITE) # Use number font
        # Position side-by-side, centered overall
        total_score_width = score_label_surf.get_width() + score_num_surf.get_width() + 5 # 5px gap
        score_label_rect = score_label_surf.get_rect(right=cfg.WIDTH // 2 - 5, centery=y_pos)
        score_num_rect = score_num_surf.get_rect(left=cfg.WIDTH // 2 + 5, centery=y_pos)
        screen.blit(score_label_surf, score_label_rect)
        screen.blit(score_num_surf, score_num_rect)
        y_pos += max(score_label_rect.height, score_num_rect.height) + 40 # Use max height, increased gap

        # High Score Info (Label + Number)
        highscore_label_surf = cfg.FONT_MAIN_MEDIUM.render("最高分: ", True, cfg.GOLD)
        highscore_num_surf = cfg.FONT_SCORE.render(str(high_score), True, cfg.GOLD) # Use number font
        total_hs_width = highscore_label_surf.get_width() + highscore_num_surf.get_width() + 5
        highscore_label_rect = highscore_label_surf.get_rect(right=cfg.WIDTH // 2 - 5, centery=y_pos)
        highscore_num_rect = highscore_num_surf.get_rect(left=cfg.WIDTH // 2 + 5, centery=y_pos)
        screen.blit(highscore_label_surf, highscore_label_rect)
        screen.blit(highscore_num_surf, highscore_num_rect)

        # --- Draw Buttons ---
        button_color = cfg.DARK_GRAY
        button_hover_color = cfg.GRAY

        # Restart Button Text Logic
        if mode_played == "关卡模式":
            restart_text = "重玩本关" if level_played is not None and level_played <= cfg.MAX_LEVEL else "返回菜单" # If all levels cleared, restart goes to menu
        else: # Traditional mode
            restart_text = "重新开始"

        # Only draw Restart button if appropriate
        if restart_text != "返回菜单":
            restart_button_rect = draw_button(screen, restart_text, (restart_x, button_y),
                                            (button_width, button_height), button_color, button_hover_color,
                                            cfg, cfg.FONT_MAIN_MEDIUM, text_color=cfg.WHITE)
        else:
            restart_button_rect = None # No restart button if all levels cleared

        # Menu Button (Always shown, unless restart text already forces menu)
        menu_button_rect = draw_button(screen, "主菜单", (menu_x, button_y),
                                       (button_width, button_height), button_color, button_hover_color,
                                       cfg, cfg.FONT_MAIN_MEDIUM, text_color=cfg.WHITE)

        # Quit Button
        quit_button_rect = draw_button(screen, "退出", (quit_x, button_y),
                                       (button_width, button_height), (150,0,0), (200,50,50),
                                       cfg, cfg.FONT_MAIN_MEDIUM, text_color=cfg.WHITE)

        pygame.display.update() # Update the entire screen

        # --- Event Handling ---
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return "QUIT"
            if event.type == pygame.MOUSEBUTTONDOWN:
                 if event.button == 1: # Left click
                    mouse_pos = event.pos
                    # Check Restart Button only if it exists
                    if restart_button_rect and restart_button_rect.collidepoint(mouse_pos):
                        return "RESTART"
                    # Check Menu Button
                    if menu_button_rect.collidepoint(mouse_pos):
                        # If restart text was "返回菜单", clicking menu does the same as restart would have
                        return "MENU"
                    # Check Quit Button
                    if quit_button_rect.collidepoint(mouse_pos):
                        return "QUIT"
            if event.type == pygame.KEYDOWN:
                 if event.key == pygame.K_ESCAPE:
                     return "QUIT"
                 elif event.key == pygame.K_r: # R for Restart
                     # Only allow R if restart is a valid option
                     if restart_text != "返回菜单":
                         return "RESTART"
                 elif event.key == pygame.K_m: # M for Menu
                     return "MENU"

def show_achievements(screen, cfg):
    """显示成就排行榜"""
    achievements = load_achievements()

    # Semi-transparent overlay
    overlay = pygame.Surface(cfg.SCREENSIZE, pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 210)) # Darker overlay

    # Draw overlay
    screen.blit(overlay, (0, 0))

    # Title
    title_surf = cfg.FONT_MAIN_XLARGE.render("成就排行榜", True, cfg.GOLD)
    title_rect = title_surf.get_rect(center=(cfg.WIDTH // 2, cfg.HEIGHT * 0.2))
    screen.blit(title_surf, title_rect)

    # Display achievements
    y_pos = title_rect.bottom + 50
    for mode, score in achievements.items():
        mode_text = f"{mode}: {score}"
        mode_surf = cfg.FONT_MAIN_MEDIUM.render(mode_text, True, cfg.WHITE)
        mode_rect = mode_surf.get_rect(center=(cfg.WIDTH // 2, y_pos))
        screen.blit(mode_surf, mode_rect)
        y_pos += mode_rect.height + 20

    # Back Button
    back_button_rect = draw_button(screen, "返回", (cfg.WIDTH // 2, cfg.HEIGHT * 0.8),
                                   (200, 60), cfg.DARK_GRAY, cfg.GRAY, cfg, cfg.FONT_MAIN_MEDIUM,
                                   text_color=cfg.WHITE)

    pygame.display.update()

    # Wait for user to click the back button
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                waiting = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1: # Left click
                    mouse_pos = event.pos
                    if back_button_rect.collidepoint(mouse_pos):
                        waiting = False
